package com.zsc.common.web.util;


import org.apache.commons.io.IOUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.*;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * Created by xbkaishui on 17/3/11.
 */
public class HttpClientUtil {

    /**
     * @param client
     * @param url
     * @param entity
     * @param headers
     * @return
     */
    public static CloseableHttpResponse post(CloseableHttpClient client, String url,
                                             HttpEntity entity, Map<String, String> headers) {
        HttpPost method = null;
        method = new HttpPost(url);
        if (entity != null) {
            method.setEntity(entity);
        }
        return doExecute(client, method, headers);

    }

    /**
     *
     *
     * @param client
     * @param url
     * @param nvps
     * @param headers
     * @return
     */
    public static CloseableHttpResponse post(CloseableHttpClient client, String url,
                                             List<org.apache.http.NameValuePair> nvps,
                                             Map<String, String> headers) {
        HttpPost method = null;
        method = new HttpPost(url);
        if (nvps != null) {
            try {
                method.setEntity(new UrlEncodedFormEntity(nvps, Charset.forName("UTF-8")));
            } catch (Exception e) {
                throw new RuntimeException("encode post parameter error!", e);
            }
        }
        return doExecute(client, method, headers);

    }

    /**
     *
     * @param client
     * @param method
     * @return
     */
    public static CloseableHttpResponse doExecute(CloseableHttpClient client,
                                                  HttpRequestBase method,
                                                  Map<String, String> headers) {
        CloseableHttpResponse resp = null;
        try {
            if (headers != null) {
                Iterator<String> headerIterator = headers.keySet().iterator();
                while (headerIterator.hasNext()) {
                    String key = headerIterator.next();
                    String val = headers.get(key);
                    method.addHeader(key, val);
                }
            }

            resp = client.execute(method);
            if (HttpStatus.SC_OK != resp.getStatusLine().getStatusCode()) {
                throw new RuntimeException("not 200!");
            }
        } catch (Exception e) {
            throw new RuntimeException("execute method error!", e);
        }
        return resp;
    }

    /**
     *
     *
     * @param client
     * @param url
     * @param entity
     * @param headers
     * @return
     */
    public static CloseableHttpResponse delete(CloseableHttpClient client, String url,
                                               HttpEntity entity, Map<String, String> headers) {
        HttpDelete method = null;
        method = new HttpDelete(url);
        return doExecute(client, method, headers);
    }

    /**
     * @param client
     * @param url
     * @param headers
     * @return
     */
    public static CloseableHttpResponse get(CloseableHttpClient client, String url,
                                            Map<String, String> headers) {
        HttpGet method = new HttpGet(url);
        return doExecute(client, method, headers);
    }

    public static CloseableHttpResponse get(CloseableHttpClient client, String url,
                                            Map<String, String> headers, Map<String, String> params) {
        HttpGet method = new HttpGet(url + getQueryString(params));
        return doExecute(client, method, headers);
    }

    /**
     * @param client
     * @param method
     * @param headers
     * @return
     */
    public static CloseableHttpResponse get(CloseableHttpClient client, HttpGet method,
                                            Map<String, String> headers) {
        return doExecute(client, method, headers);
    }

    /**
     * 下载文件
     *
     * @param client
     * @param url
     * @param headers
     */
    public static boolean download(CloseableHttpClient client, String url,
                                   Map<String, String> headers, String filePath) {
        CloseableHttpResponse resp = get(client, url, headers);
        HttpEntity entity = resp.getEntity();
        OutputStream oos = null;
        boolean flag = true;
        try {
            InputStream ins = entity.getContent();
            oos = new FileOutputStream(new File(filePath));
            IOUtils.copy(ins, oos);
        } catch (Exception e) {
            flag = false;
            e.printStackTrace();
        } finally {
            EntityUtils.consumeQuietly(entity);
            IOUtils.closeQuietly(oos);
        }
        return flag;
    }

    private static String getQueryString(Map<String, String> params) {
        if (params == null || params.isEmpty()) {
            return "";
        }
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, String> entry : params.entrySet()) {
            sb.append(entry.getKey() + "=" + entry.getValue() + "&");
        }

        if (sb.length() > 0) {
            sb.insert(0, "?");
            sb.deleteCharAt(sb.length() - 1);
        }

        return sb.toString();
    }

}
